msg_tool\scripts\escude/
crypto.rs1use crate::ext::io::*;
2use anyhow::Result;
3use rand::Rng;
4use std::io::{Read, Seek, Write};
5
6pub struct CryptoReader<T: Read + Seek> {
7 reader: T,
8 _key: u32,
9 max_pos: u32,
10}
11
12impl<T: Read + Seek> CryptoReader<T> {
13 pub fn new(mut reader: T) -> Result<Self> {
14 let _key = reader.peek_u32_at(0x8)?;
15 let mut s = CryptoReader {
16 reader,
17 _key,
18 max_pos: 0,
19 };
20 s.init()?;
21 Ok(s)
22 }
23
24 fn key(&mut self) -> u32 {
25 self._key ^= 0x65AC9365;
26 self._key ^= (((self._key >> 1) ^ self._key) >> 3) ^ (((self._key << 1) ^ self._key) << 3);
27 return self._key;
28 }
29
30 fn init(&mut self) -> Result<()> {
31 let _key = self._key;
32 self.max_pos = (self.reader.peek_u32_at(0xC)? ^ self.key()) * 12 + 0xC;
33 self._key = _key;
34 Ok(())
35 }
36}
37
38impl<T: Read + Seek> Read for CryptoReader<T> {
39 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
40 let remaing = self.max_pos as usize + 0x8 - self.reader.stream_position()? as usize;
41 let count = buf.len().min(remaing);
42 let readed = self.reader.read(&mut buf[..count])?;
43 for i in 0..readed / 4 {
44 let val = u32::from_le_bytes(buf[i * 4..i * 4 + 4].try_into().map_err(|_| {
45 std::io::Error::new(
46 std::io::ErrorKind::InvalidData,
47 "Failed to convert slice to u32",
48 )
49 })?);
50 let decrypted = val ^ self.key();
51 buf[i * 4..i * 4 + 4].copy_from_slice(&decrypted.to_le_bytes());
52 }
53 Ok(readed)
54 }
55}
56
57pub struct CryptoWriter<T: Write + Seek> {
58 writer: T,
59 key: u32,
60 in_buffer: Vec<u8>,
61}
62
63impl<T: Write + Seek> CryptoWriter<T> {
64 pub fn new(mut writer: T) -> Result<Self> {
65 let mut rng = rand::rng();
66 let key = rng.random();
67 writer.write_u32(key)?;
68 Ok(Self {
69 writer,
70 key,
71 in_buffer: Vec::new(),
72 })
73 }
74
75 fn key(&mut self) -> u32 {
76 self.key ^= 0x65AC9365;
77 self.key ^= (((self.key >> 1) ^ self.key) >> 3) ^ (((self.key << 1) ^ self.key) << 3);
78 return self.key;
79 }
80}
81
82impl<T: Write + Seek> Write for CryptoWriter<T> {
83 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
84 self.in_buffer.extend_from_slice(buf);
85 while self.in_buffer.len() >= 4 {
86 let mut val = self.in_buffer.as_slice().read_u32()?;
87 val ^= self.key();
88 self.writer.write_u32(val)?;
89 self.in_buffer.drain(0..4);
90 }
91 Ok(buf.len())
92 }
93
94 fn flush(&mut self) -> std::io::Result<()> {
95 self.writer.flush()
96 }
97}